import { Bounds, getLocalBounds, Matrix, PointData } from "pixi.js";
import { BaseEntity } from "./BaseEntity";
import { PixijsEntity } from "./PixijsEntities";


const __baseEntity = new BaseEntity();
const __bounds = new Bounds();

interface TransformableObject {
    position: { x: number, y: number };
    scale: { x: number, y: number };
    pivot: { x: number, y: number };
    skew: { x: number, y: number };
    rotation: number;
}

interface NumberObject {
    [key: string]: number | NumberObject; // 支持嵌套对象
}

export function formatNumbers(obj: NumberObject | number): any {
    if(typeof obj === 'number') return Math.floor(obj * 100) / 100;
    
    for (const key in obj) {
        if (typeof obj[key] === 'number') {
            // 保留两位小数
            obj[key] = Math.floor(obj[key] as number * 100) / 100;
        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
            // 递归处理嵌套对象
            obj[key] = formatNumbers(obj[key] as NumberObject);
        } 
    }

    return obj;
}

export function setWorldTransform(entity: BaseEntity, worldMat: Matrix) {
    let t = {
        position: { x: 0, y: 0 },
        scale: { x: 0, y: 0 },
        pivot: { x: 0, y: 0 },
        skew: { x: 0, y: 0 },
        rotation: 0,
    }

    let parentMat = entity.view.parent.worldTransform.clone()
    parentMat = parentMat.invert()
    parentMat = parentMat.append(worldMat)
    parentMat.decompose(t);

    entity.position.x = t.position.x;
    entity.position.y = t.position.y;
    entity.scale.x = t.scale.x;
    entity.scale.y = t.scale.y;
    entity.skew.x = t.skew.x;
    entity.skew.y = t.skew.y;
    entity.rotation = t.rotation/Math.PI*180;
    entity.view.position.set(t.position.x, t.position.y);
    entity.view.scale.set(t.scale.x, t.scale.y);
    entity.view.rotation = t.rotation;
    entity.view.skew.set(t.skew.x, t.skew.y);
}

export function decompose(mat: Matrix, transform: TransformableObject): TransformableObject {
    const a = mat.a;
    const b = mat.b;
    const c = mat.c;
    const d = mat.d;
    const pivot = transform.pivot;

    // 处理旋转
    transform.rotation = Math.atan2(b, a); // 计算旋转

    // 去除剪切，直接设置为 0
    transform.skew.x = 0;
    transform.skew.y = 0;

    // 计算有符号的缩放
    transform.scale.x = Math.sqrt(a * a + b * b) * Math.sign(a);
    transform.scale.y = Math.sqrt(c * c + d * d) * Math.sign(d);

    // 设置位置
    transform.position.x = mat.tx + ((pivot.x * a) + (pivot.y * c));
    transform.position.y = mat.ty + ((pivot.x * b) + (pivot.y * d));

    return transform;
}

export function findCommonAncestor(entities: BaseEntity[]): BaseEntity | null {
    if (entities.length === 0) return null;

    // 获取所有祖先
    function getAncestors(entity: BaseEntity): BaseEntity[] {
        const ancestors = [];
        let current = entity;
        while (current.parent) {
            ancestors.push(current.parent);
            current = current.parent;
        }
        return ancestors;
    }

    // 获取第一个实体的所有祖先
    const firstAncestors = getAncestors(entities[0]);

    // 遍历其他实体，找到共同祖先
    for (let i = 1; i < entities.length; i++) {
        const currentAncestors = new Set(getAncestors(entities[i]));
        for (let j = firstAncestors.length - 1; j >= 0; j--) {
            if (!currentAncestors.has(firstAncestors[j])) {
                firstAncestors.splice(j, 1);
            }
        }
    }

    // 返回最近的共同祖先
    return firstAncestors.length > 0 ? firstAncestors[0] : null;
}

export function getPerpendicularFoot(mousePos: { x: number; y: number }, start: { x: number; y: number }, end: { x: number; y: number }): { x: number; y: number } {
    const x1 = start.x;
    const y1 = start.y;
    const x2 = end.x;
    const y2 = end.y;

    // 计算线段的长度
    const dx = x2 - x1;
    const dy = y2 - y1;
    const lineLengthSquared = dx * dx + dy * dy;

    // 如果线段的长度为零，返回起点
    if (lineLengthSquared === 0) {
        return { x: x1, y: y1 };
    }

    // 计算点到线段的投影比例
    const t = ((mousePos.x - x1) * dx + (mousePos.y - y1) * dy) / lineLengthSquared;

    // 限制 t 的范围在 [0, 1] 之间
    const clampedT = Math.max(0, Math.min(1, t));

    // 计算垂足的坐标
    const footX = x1 + clampedT * dx;
    const footY = y1 + clampedT * dy;

    return { x: footX, y: footY };
}

export function getNonFunctionProperties(inst: any) {
    if(!inst) return;
    const baseProperties = new Set(Object.keys(__baseEntity));
    const properties: { [key: string]: any } = {};

    Object.entries(inst).forEach(([key, value]) => {
        if (!baseProperties.has(key) && !key.startsWith('__') && typeof value !== 'function') {
            properties[key] = value;
        }
    });
    return properties;
}

export function isPointInRectangle(a: PointData, b: PointData, c: PointData, d: PointData, p: PointData): boolean {
    // 计算向量 AB 和 AP
    const crossProduct = (p1: PointData, p2: PointData, p3: PointData): number => {
        return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
    };

    // 判断点 p 是否在矩形内
    const abAp = crossProduct(a, b, p);
    const bcBp = crossProduct(b, c, p);
    const cdDp = crossProduct(c, d, p);
    const daAp = crossProduct(d, a, p);

    // 如果点 p 在矩形的四条边的同侧，则在矩形内
    return (abAp >= 0 && bcBp >= 0 && cdDp >= 0 && daAp >= 0) || 
           (abAp <= 0 && bcBp <= 0 && cdDp <= 0 && daAp <= 0);
}

export function getControlPoints(entity: PixijsEntity) {
    if (!entity.view) return;
    getLocalBounds(entity.view, __bounds);
    const { x: offsetX, y: offsetY, width, height } = __bounds;

    const points = [
        { x: offsetX, y: offsetY }, // 左上 0
        { x: offsetX + width, y: offsetY }, // 右上 1
        { x: offsetX + width, y: offsetY + height }, // 右下 2
        { x: offsetX, y: offsetY + height }, // 左下 3
        { x: offsetX + width / 2, y: offsetY }, // 上中 4
        { x: offsetX + width, y: offsetY + height / 2 }, // 右中 5
        { x: offsetX + width / 2, y: offsetY + height }, // 下中 6
        { x: offsetX, y: offsetY + height / 2 }, // 左中 7
    ];
    
    const rotatedPoints = points.map(point => {
        return entity.view.toGlobal(point)
    });

    //console.log(rotatedPoints[1].x, rotatedPoints[1].y)
    return rotatedPoints;
}

export function getEntities(entities: BaseEntity){
    let allEntities: BaseEntity[] = [...entities.children]; // 初始化为当前实体的直接子实体

    // 递归获取所有子实体
    for (const child of entities.children) {
        allEntities = allEntities.concat(getEntities(child));
    }

    return allEntities;
}
